package cdms.web;

import java.util.List;

/**
 * 
 * Paging assistant
 * 
 * @author fengduxin
 * @version 1.0
 *
 */
public class PaginationSupport<T> {

	/**
	 * default page size
	 */
	public final static int PAGESIZE = 10;

	/**
	 * page size
	 */
	private int pageSize = PAGESIZE;

	/**
	 * data of records
	 */
	private List<T> items;

	/**
	 * count of records
	 */
	private int totalCount;

	/**
	 * the array of start index of each page
	 */
	private int[] indexes = new int[0];

	/**
	 * the current start index
	 */
	private int startIndex = 0;

	/**
	 * Constructor
	 * 
	 * @param items
	 *            data of records
	 * @param totalCount
	 *            count of records
	 */
	public PaginationSupport(List<T> items, int totalCount) {
		setPageSize(PAGESIZE);
		setTotalCount(totalCount);
		setItems(items);
		setStartIndex(0);
	}

	/**
	 * Constructor
	 * 
	 * @param items
	 *            data of records
	 * @param totalCount
	 *            count of records
	 * @param startIndex
	 *            the current start index
	 */
	public PaginationSupport(List<T> items, int totalCount, int startIndex) {
		setPageSize(PAGESIZE);
		setTotalCount(totalCount);
		setItems(items);
		setStartIndex(startIndex);
	}

	/**
	 * Constructor
	 * 
	 * @param items
	 *            data of records
	 * @param totalCount
	 *            count of records
	 * @param pageSize
	 *            size of page
	 * @param startIndex
	 *            the current start index
	 */
	public PaginationSupport(List<T> items, int totalCount, int pageSize, int startIndex) {
		setPageSize(pageSize);
		setTotalCount(totalCount);
		setItems(items);
		setStartIndex(startIndex);
	}

	/**
	 * get the current start index, the page size is default.
	 * 
	 * @param pageNo
	 *            page number
	 * @return the current start index
	 */
	public static int convertFromPageToStartIndex(int pageNo) {
		return (pageNo - 1) * PAGESIZE;
	}

	/**
	 * get the current start index
	 * 
	 * @param pageNo
	 *            page number
	 * @param pageSize
	 *            size of page
	 * @return the current start index
	 */
	public static int convertFromPageToStartIndex(int pageNo, int pageSize) {
		return (pageNo - 1) * pageSize;
	}

	/**
	 * get data of records
	 * 
	 * @return data of records
	 */
	public List<T> getItems() {
		return items;
	}

	/**
	 * set data of records
	 * 
	 * @param items
	 *            data of records
	 */
	public void setItems(List<T> items) {
		this.items = items;
	}

	/**
	 * get size of page
	 * 
	 * @return size of page
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * set size of page
	 * 
	 * @param pageSize
	 *            size of page
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * get count of records
	 * 
	 * @return count of records
	 */
	public int getTotalCount() {
		return totalCount;
	}

	/**
	 * set count of records, and calculate start index of each page.
	 * 
	 * @param totalCount
	 *            count of records
	 */
	public void setTotalCount(int totalCount) {
		if (totalCount > 0) {
			this.totalCount = totalCount;
			int count = totalCount / pageSize;
			if (totalCount % pageSize > 0)
				count++;
			indexes = new int[count];
			for (int i = 0; i < count; i++) {
				indexes[i] = pageSize * i;
			}
		} else {
			this.totalCount = 0;
		}
	}

	/**
	 * get the array of start index of each page
	 * 
	 * @return the array of start index of each page
	 */
	public int[] getIndexes() {
		return indexes;
	}

	/**
	 * set the array of start index of each page
	 * 
	 * @param indexes
	 *            the array of start index of each page
	 */
	public void setIndexes(int[] indexes) {
		this.indexes = indexes;
	}

	/**
	 * get the current start index
	 * 
	 * @return the current start index
	 */
	public int getStartIndex() {
		return startIndex;
	}

	/**
	 * set the current start index
	 * 
	 * @param startIndex
	 *            the current start index
	 */
	public void setStartIndex(int startIndex) {
		if (totalCount <= 0)
			this.startIndex = 0;
		else if (startIndex >= totalCount)
			this.startIndex = indexes[indexes.length - 1];
		else if (startIndex < 0)
			this.startIndex = 0;
		else {
			this.startIndex = indexes[startIndex / pageSize];
		}
	}

	/**
	 * get the start index of next page
	 * 
	 * @return the start index of next page
	 */
	public int getNextIndex() {
		int nextIndex = getStartIndex() + pageSize;
		if (nextIndex >= totalCount)
			return getStartIndex();
		return nextIndex;
	}

	/**
	 * get the start index of previous page
	 * 
	 * @return the start index of previous page
	 */
	public int getPreviousIndex() {
		int previousIndex = getStartIndex() - pageSize;
		if (previousIndex < 0)
			return 0;
		return previousIndex;
	}

	/**
	 * get the count of records
	 * 
	 * @return the count of records
	 */
	public long getTotalPageCount() {
		if (totalCount % pageSize == 0)
			return totalCount / pageSize;
		return totalCount / pageSize + 1;
	}

	/**
	 * get the current page number, "1" is the first page number
	 * 
	 * @return the current page number
	 */
	public long getCurrentPageNo() {
		return startIndex / pageSize + 1;
	}

	/**
	 * judge for next page
	 * 
	 * @return true for there is, false for there is not
	 */
	public boolean isNextPage() {
		return this.getCurrentPageNo() < this.getTotalPageCount();
	}

	/**
	 * judge for previous page
	 * 
	 * @return true for there is, false for there is not
	 */
	public boolean isPreviousPage() {
		return this.getCurrentPageNo() > 1;
	}
}
